home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 11 / FM Towns Free Software Collection 11.iso / t_os / tool / artemis1 / src / copy.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-10-19  |  17.7 KB  |  812 lines

  1. /*
  2.     ARTemis (Graphic Editor for FM-TOWNS)
  3.     (c) MATSUUCHI Ryosuke 1992,1993
  4.  
  5.     copy.c
  6.  
  7.     「コピー」コマンド
  8.     「拡大・縮小」コマンド
  9. */
  10.  
  11.  
  12. #include <stdio.h>
  13. #include <malloc.h>
  14. #include <memory.h>
  15. #include "ge.h"
  16. #include "dispman.h"
  17. #include "imageman.h"
  18.  
  19.  
  20. #define    BLACK_PARA    10
  21.  
  22.  
  23. static void matte_wordset(short *dp, int col, int op)
  24. // dp:書き込み先
  25. {
  26.     int mix = getmixrate();
  27.     if (mode == MODE32K && op == DrawMATTE && blkop_edge)
  28.     {
  29.         int b = coldiff(col, backcol);
  30.         if (b <= BLACK_PARA)
  31.         {
  32.             int c;
  33.             c = colmazeru(*dp, col, (b*256+BLACK_PARA/2)/BLACK_PARA);
  34.             *dp = graycol(*dp,c,mix);
  35.         }
  36.         else
  37.             *dp = graycol(*dp,col,mix);
  38.     }
  39.     else if (op == DrawMATTE)
  40.     {
  41.         if (col != backcol)
  42.             *dp = graycol(*dp,col,mix);
  43.     }
  44.     else if (mix == 256)
  45.         *dp = col;
  46.     else
  47.         *dp = graycol(*dp,col,mix);
  48. }
  49.  
  50.  
  51. void matte_hline_map(int x, int x2, int y, char *lbuf, int op)
  52. {
  53.     char *dp0 = EIMadrs(x,y);
  54.     int mix = getmixrate();
  55.     if (mode == MODE32K && op == DrawMATTE && blkop_edge)
  56.     {
  57.         short *dp,*sp;
  58.  
  59.         void hline(int _x1, int _x2, int _y)
  60.         {
  61.             int i;
  62.             short *dp,*sp;
  63.             dp = (short*)dp0  + _x1 - x;
  64.             sp = (short*)lbuf + _x1 - x;
  65.             for (i=_x1; i<=_x2; i++,sp++,dp++)
  66.             {
  67.                 int b = coldiff(*sp, backcol);
  68.                 if (b <= BLACK_PARA)
  69.                   { int c=colmazeru(*dp,*sp,(b*256+BLACK_PARA/2)/BLACK_PARA);
  70.                     *dp = graycol(*dp,c,mix); }
  71.                 else
  72.                     *dp = graycol(*dp,*sp,mix);
  73.             }
  74.         }
  75.  
  76.         hline_func(x,x2,y, hline);
  77.     }
  78.     else if (op == DrawMATTE)
  79.     {
  80.         void hline(int _x1, int _x2, int _y)
  81.         {
  82.             short *dp = (short*)dp0  + _x1 - x, *sp = (short*)lbuf + _x1 - x;
  83.             for (int i=_x1; i<=_x2; i++,sp++,dp++)
  84.                 { if (*sp != backcol)  *dp = graycol(*dp,*sp,mix); }
  85.         }
  86.         hline_func(x,x2,y, hline);
  87.     }
  88.     else if (mix == 256)
  89.     {
  90.         void hline(int _x1, int _x2, int _y)
  91.         {
  92.             memcpy(dp0+(_x1-x)*2,lbuf+(_x1-x)*2,(_x2-_x1+1)*2);
  93.         }
  94.         hline_func(x,x2,y, hline);
  95.     }
  96.     else
  97.     {
  98.         void hline(int _x1, int _x2, int _y)
  99.         {
  100.             short *dp = (short*)dp0+_x1-x,  *sp = (short*)lbuf+_x1-x;
  101.             for (int i=_x1; i<=_x2; i++,sp++,dp++)
  102.                 *dp = graycol(*dp,*sp,mix);
  103.         }
  104.         hline_func(x,x2,y, hline);
  105.     }
  106.     DMimage_hline_map(x,x2,y,dp0);
  107. }
  108.  
  109. void matte_putblock(int x,int y,int xlen,int ylen,char *buf,int op)
  110. {
  111.     int i;
  112.     for (i=0; i<ylen; i++)
  113.         matte_hline_map(x,x+xlen-1,y+i, buf+xlen*2*i, op);
  114. }
  115.  
  116. void matte_pset(int x, int y, int col, int op)
  117. {
  118.     int mix = getmixrate();
  119.     if (mode == MODE32K && op == DrawMATTE && blkop_edge)
  120.     {
  121.         int b = coldiff(col, backcol);
  122.         if (b <= BLACK_PARA)
  123.         {
  124.             int c;
  125.             c = EIMpoint(x,y);
  126.             c = colmazeru(c, col, (b*256+BLACK_PARA/2)/BLACK_PARA);
  127.             EIMgraypset(x,y,c,mix);
  128.         }
  129.         else
  130.             EIMgraypset(x,y,col,mix);
  131.     }
  132.     else if (op == DrawMATTE)
  133.     {
  134.         if (col != backcol)
  135.             EIMgraypset(x,y,col,mix);
  136.     }
  137.     else if (op == DrawNORMAL)
  138.     {
  139.         EIMgraypset(x,y,col,mix);
  140.     }
  141.     else
  142.         EIMpset(x,y,col,op);
  143. }
  144.  
  145. /*
  146.     1ラインの拡大/縮小
  147. */
  148.  
  149. static void line_expand(char *outbuf, int outlen, char *inbuf, int inlen)
  150. {
  151.     int i; int col1,col2; bool col1a,col2a;
  152.     int r,rsx;
  153.     if (outlen <= 1)
  154.     {
  155.         *(short*)outbuf = *(short*)inbuf;
  156.         return;
  157.     }
  158.     r = ((inlen-1) << 16) / (outlen-1);
  159.     rsx = 0;
  160.     col1a = col2a = NO;
  161.     for (i=0; i<outlen; i++,rsx+=r)
  162.     {
  163.         int outcol;
  164.         if ((rsx & 0xff00) == 0)
  165.         {
  166.             if (col2a)
  167.                 col1 = col2, col1a = YES, col2a = NO;
  168.             else
  169.                 col1 = *(short*)(inbuf+(rsx>>16)*2), col1a = YES;
  170.             outcol = col1;
  171.         }
  172.         else if ((rsx>>16)!=((rsx-r)>>16))
  173.         {
  174.             if (col2a)
  175.                 col1 = col2, col1a=YES;
  176.             else
  177.                 col1 = *(short*)(inbuf+(rsx>>16)*2), col1a=YES;
  178.             col2 = *(short*)(inbuf+(rsx>>16)*2+2), col2a=YES;
  179.             outcol = colmazeru(col1,col2,(rsx>>8)&0xff);
  180.         }
  181.         else
  182.         {
  183.             if (!col2a)
  184.                 col2 = *(short*)(inbuf+(rsx>>16)*2+2), col2a=YES;
  185.             outcol = colmazeru(col1,col2,(rsx>>8)&0xff);
  186.         }
  187.         *(short*)(outbuf + i*2) = outcol;
  188.     }
  189. }
  190.  
  191. static void line_shorten(char *outbuf, int outlen, char *inbuf, int inlen)
  192. {
  193.     int r,rsx;
  194.     int i,sx;
  195.     r = (outlen << 16) / inlen;
  196.     int rgb[3];
  197.     int magsum;
  198.     for (i=0,rsx = 0,sx=0; i<outlen; i++)
  199.     {
  200.         bool end = NO, first = YES;
  201.         rgb[0] = rgb[1] = rgb[2] = 0;
  202.         magsum = 0;
  203.         while (!end)
  204.         {
  205.             int mag, sc = *(short*)(inbuf + sx*2);
  206.             int rsxa = rsx + r;
  207.             if ((rsx & 0xffff0000) == (rsxa & 0xffff0000))
  208.                 mag = 256, rsx += r, sx++;
  209.             else if ((rsxa & 0xff00) != 0)
  210.             {
  211.                 mag = 256 - ((rsxa & 0xff00) >> 8);
  212.                 if (!first)
  213.                     end = YES;
  214.                 else
  215.                     rsx += r, sx++;
  216.             }
  217.             else
  218.                 mag = 256, rsx += r, sx++, end = YES;
  219.             rgb[0]+=getR(sc)*mag, rgb[1]+=getG(sc)*mag, rgb[2]+=getB(sc)*mag;
  220.             magsum += mag;
  221.             first = NO;
  222.         }
  223.         int t = magsum/2;
  224.         *(short*)(outbuf+i*2) =
  225.             GRB((rgb[1]+t)/magsum,(rgb[0]+t)/magsum,(rgb[2]+t)/magsum);
  226.     }
  227. }
  228.  
  229. static void line_zoom(char *outbuf, int outlen, char *inbuf, int inlen)
  230. {
  231.     if (outlen == 0 || inlen == 0)
  232.         return;
  233.     if (outlen >= inlen)
  234.         line_expand(outbuf, outlen, inbuf, inlen);
  235.     else
  236.         line_shorten(outbuf, outlen, inbuf, inlen);
  237. }
  238.  
  239.  
  240. /*
  241.     ライン単位の処理のためのバッファを生成/消滅する
  242. */
  243.  
  244. static char *LINnew()
  245. {
  246.     return malloc(EIMgetxsize()*2);
  247. }
  248.  
  249. static void LINdelete(char *lin)
  250. {
  251.     free(lin);
  252. }
  253.  
  254. /*
  255.     ライン単位の混色のための関数群
  256. */
  257.  
  258. typedef char*    LMIX;
  259. // 0~3:バッファの大きさ  4~7:magsum  8~:rgblist
  260.  
  261. static LMIX    LMIXnew()
  262. {
  263.     char *p;  int size;
  264.     size = 4 + 4 + 12 * EIMgetxsize();
  265.     if ((p = malloc(size)) == NULL)
  266.         return p;
  267.     memset(p,0,size);
  268.     *(int*)p = size;
  269.     return (LMIX)p;
  270. }
  271.  
  272. static void LMIXdelete(LMIX l)
  273. {
  274.     free(l);
  275. }
  276.  
  277. static void LMIXclear(LMIX l)
  278. {
  279.     int size = *(int*)l;
  280.     memset((char*)l+4, 0, size-4);
  281. }
  282.  
  283. static void LMIXaddline(LMIX l, char *line, int xlen, int mag)
  284. {
  285.     int *dp = (int*)((char*)l+8);
  286.     short *sp = (short*)line;
  287.     int i;
  288.     for (i=0; i<xlen; i++,sp++)
  289.     {
  290.         int sc = *sp;
  291.         *dp++ += getR(sc)*mag, *dp++ += getG(sc)*mag, *dp++ += getB(sc)*mag;
  292.     }
  293.     *((int*)l+1) += mag;
  294. }
  295.  
  296. static void LMIXgetaverage(char *outbuf, int xlen, LMIX l)
  297. {
  298.     int *sp = (int*)((char*)l+8);
  299.     short *dp = (short*)outbuf;
  300.     int i,magsum,h;
  301.     magsum = *((int*)l+1);
  302.     h = magsum/2;
  303.     for (i=0; i<xlen; i++,dp++,sp+=3)
  304.         *dp = GRB((*(sp+1)+h)/magsum,(*sp+h)/magsum,(*(sp+2)+h)/magsum);
  305. }
  306.  
  307.  
  308. static void box_expand(    int dx,int dy,int dxlen,int dylen,
  309.                         int sx,int sy,int sxlen,int sylen,
  310.                         bool matte_sw, bool area_sw )
  311. {
  312.     char *lbuf1,*lbuf2,*outlbuf;
  313.     LMIX mixbuf;
  314.     if ((lbuf1 = LINnew()) == NULL)
  315.         goto nomem;
  316.     if ((lbuf2 = LINnew()) == NULL)
  317.         { LINdelete(lbuf1); goto nomem; }
  318.     if ((outlbuf = LINnew()) == NULL)
  319.         { LINdelete(lbuf2); LINdelete(lbuf1); goto nomem; }
  320.     if ((mixbuf = LMIXnew()) == NULL)
  321.         { LINdelete(outlbuf); LINdelete(lbuf2); LINdelete(lbuf1); goto nomem; }
  322.     int i; bool col1a,col2a;
  323.     int r,rsy;
  324.     if (dylen <= 1)
  325.     {
  326.         line_zoom(lbuf1,dxlen,EIMadrs_back(sx,sy),sxlen);
  327.         matte_hline_map(dx,dx+dxlen-1,dy,lbuf1,
  328.                         (matte_sw ? DrawMATTE:DrawNORMAL));
  329.     }
  330.     else
  331.     {
  332.         r = ((sylen-1) << 16) / (dylen-1);
  333.         rsy = sy << 16;
  334.         col1a = col2a = NO;
  335.         for (i=0; i<dylen; i++,rsy+=r)
  336.         {
  337.             if ((rsy & 0xff00) == 0)
  338.             {
  339.                 if (col2a)
  340.                     memcpy(lbuf1,lbuf2,dxlen*2), col1a = YES, col2a = NO;
  341.                 else
  342.                 {
  343.                     line_zoom(lbuf1,dxlen,EIMadrs_back(sx,rsy>>16),sxlen);
  344.                     col1a = YES;
  345.                 }
  346.                 memcpy(outlbuf,lbuf1,dxlen*2);
  347.             }
  348.             else if ((rsy>>16)!=((rsy-r)>>16))
  349.             {
  350.                 if (col2a)
  351.                     memcpy(lbuf1,lbuf2,dxlen*2), col1a=YES;
  352.                 else
  353.                 {
  354.                     line_zoom(lbuf1,dxlen,EIMadrs_back(sx,rsy>>16),sxlen);
  355.                     col1a = YES;
  356.                 }
  357.                 line_zoom(lbuf2,dxlen,EIMadrs_back(sx,(rsy>>16)+1),sxlen);
  358.                 col2a=YES;
  359.                 LMIXclear(mixbuf);
  360.                 LMIXaddline(mixbuf, lbuf1, dxlen, 256-((rsy>>8)&0xff));
  361.                 LMIXaddline(mixbuf, lbuf2, dxlen, (rsy>>8)&0xff);
  362.                 LMIXgetaverage(outlbuf, dxlen, mixbuf);
  363.             }
  364.             else
  365.             {
  366.                 if (!col2a)
  367.                 {
  368.                     line_zoom(lbuf2,dxlen,EIMadrs_back(sx,(rsy>>16)+1),sxlen);
  369.                     col2a=YES;
  370.                 }
  371.                 LMIXclear(mixbuf);
  372.                 LMIXaddline(mixbuf, lbuf1, dxlen, 256-((rsy>>8)&0xff));
  373.                 LMIXaddline(mixbuf, lbuf2, dxlen, (rsy>>8)&0xff);
  374.                 LMIXgetaverage(outlbuf, dxlen, mixbuf);
  375.             }
  376.             if (!area_sw)
  377.                 matte_hline_map(dx,dx+dxlen-1,dy+i,outlbuf,
  378.                                 (matte_sw ? DrawMATTE:DrawNORMAL));
  379.             else
  380.             {
  381.                 char *dp0 = EIMadrs(dx,dy+i);
  382.                 int rsx0,r,op;
  383.                 rsx0 = sx << 16,  r = (sxlen<<16)/dxlen;
  384.                 op = (matte_sw ? DrawMATTE:DrawNORMAL);
  385.                 void hline(int _x1, int _x2, int _y)
  386.                 {
  387.                     short *dp = (short*)dp0+_x1-dx;
  388.                     int rsx = rsx0 + r * (_x1-dx);
  389.                     for (int j=_x1; j<=_x2; j++,rsx+=r,dp++)
  390.                         if (area_chkxy(rsx>>16,rsy>>16))
  391.                             matte_wordset(dp,*((short*)outlbuf+(j-dx)),op);
  392.                     DMimage_hline_map(_x1,_x2,_y,(char*)((short*)dp0+_x1-dx));
  393.                 }
  394.                 hline_func(dx, dx+dxlen-1, dy+i, hline);
  395.             }
  396.         }
  397.     }
  398.     LMIXdelete(mixbuf);
  399.     LINdelete(outlbuf);
  400.     LINdelete(lbuf2);
  401.     LINdelete(lbuf1);
  402.     return;
  403. nomem:
  404.     dispAttentionMsg("記憶容量不足のため、拡大/縮小処理が行えません");
  405. }
  406.  
  407. static void box_shorten(int dx,int dy,int dxlen,int dylen,
  408.                         int sx,int sy,int sxlen,int sylen,
  409.                         bool matte_sw, bool area_sw )
  410. {
  411.     char *lbuf1,*outlbuf;
  412.     LMIX mixbuf;
  413.     if ((lbuf1 = LINnew()) == NULL)
  414.         goto nomem;
  415.     if ((outlbuf = LINnew()) == NULL)
  416.         { LINdelete(lbuf1); goto nomem; }
  417.     if ((mixbuf = LMIXnew()) == NULL)
  418.         { LINdelete(outlbuf); LINdelete(lbuf1); goto nomem; }
  419.     int r,rsy;
  420.     int i,bufy,sy0=sy;
  421.     if (sylen == 0)
  422.         return;
  423.     r = (dylen << 16) / sylen;
  424.     bufy = -1;
  425.     for (i=0,rsy=sy<<16; i<dylen; i++)
  426.     {
  427.         bool end = NO, first = YES;
  428.         LMIXclear(mixbuf);
  429.         while (!end)
  430.         {
  431.             int mag;
  432.             if (sy != bufy)
  433.             {
  434.                 line_zoom(lbuf1,dxlen,EIMadrs_back(sx,sy),sxlen);
  435.                 bufy = sy;
  436.             }
  437.             int rsya = rsy + r;
  438.             if ((rsy & 0xffff0000) == (rsya & 0xffff0000))
  439.                 mag = 256, rsy += r, sy++;
  440.             else if ((rsya & 0xff00) != 0)
  441.             {
  442.                 mag = 256 - ((rsya & 0xff00) >> 8);
  443.                 if (!first)
  444.                     end = YES;
  445.                 else
  446.                     rsy += r, sy++;
  447.             }
  448.             else
  449.                 mag = 256, rsy += r, sy++, end = YES;
  450.             LMIXaddline(mixbuf, lbuf1, dxlen, mag);
  451.             first = NO;
  452.         }
  453.         LMIXgetaverage(outlbuf, dxlen, mixbuf);
  454.         if (!area_sw)
  455.         {
  456.             matte_hline_map(dx,dx+dxlen-1,dy+i,outlbuf,
  457.                             (matte_sw ? DrawMATTE:DrawNORMAL));
  458.         }
  459.         else
  460.         {
  461.             char *dp0 = EIMadrs(dx,dy+i);
  462.             int rsx0,r,op;
  463.             rsx0 = sx << 16,  r = (sxlen<<16)/dxlen;
  464.             op = (matte_sw ? DrawMATTE:DrawNORMAL);
  465.             int _sy,h=(dylen-1)/2;
  466.             _sy = sy0 + (dylen <= 1 ? 0 : ((sylen-1)*i+h)/(dylen-1));
  467.             void hline(int _x1, int _x2, int _y)
  468.             {
  469.                 short *dp = (short*)dp0 + _x1-dx;
  470.                 int rsx = rsx0 + r * (_x1-dx);
  471.                 for (int j=_x1; j<=_x2; j++,rsx+=r,dp++)
  472.                     if (area_chkxy(rsx>>16,_sy))
  473.                         matte_wordset(dp,*((short*)outlbuf+j-dx),op);
  474.                 DMimage_hline_map(_x1,_x2,_y,(char*)((short*)dp0+_x1-dx));
  475.             }
  476.             hline_func(dx,dx+dxlen-1,dy+i,hline);
  477.         }
  478.     }
  479.     LMIXdelete(mixbuf);
  480.     LINdelete(outlbuf);
  481.     LINdelete(lbuf1);
  482.     return;
  483. nomem:
  484.     dispAttentionMsg("記憶容量不足のため、拡大/縮小処理が行えません");
  485. }
  486.  
  487.  
  488.  
  489.  
  490. void zoomcopy(int sx1, int sy1, int sx2, int sy2,
  491.               int dx1, int dy1, int dx2, int dy2,
  492.               bool matte_sw, bool area_sw)
  493. // matte_sw : 半透明指定を有効化するスイッチ(通常 ON, view時 OFF)
  494. // area_sw  : 領域指定を有効化するスイッチ
  495. {
  496.     // 縮小処理
  497.     //   8ビット固定小数で計算
  498. #define    _swap(a,b)    { int t; t=(a); (a)=(b); (b)=t; }
  499.     if (sx2 < sx1)
  500.         _swap(sx1,sx2);
  501.     if (sy2 < sy1)
  502.         _swap(sy1,sy2);
  503.     if (dx2 < dx1)
  504.         _swap(dx1,dx2);
  505.     if (dy2 < dy1)
  506.         _swap(dy1,dy2);
  507.     int sxl,syl,dxl,dyl;
  508.     sxl = sx2-sx1+1;
  509.     syl = sy2-sy1+1;
  510.     dxl = dx2-dx1+1;
  511.     dyl = dy2-dy1+1;
  512.     int x,y;
  513.     if (mode == MODE32K)
  514.     {
  515.         if (dyl < syl)
  516.             box_shorten(dx1,dy1,dxl,dyl, sx1,sy1,sxl,syl, matte_sw, area_sw);
  517.         else
  518.             box_expand(dx1,dy1,dxl,dyl, sx1,sy1,sxl,syl, matte_sw, area_sw);
  519.     }
  520.     else     // 16色モード
  521.     {
  522. #if    NO16==0
  523.         for (y=dy1; y<=dy2; y++)
  524.         {
  525.             for (x=dx1; x<=dx2; x++)
  526.             {
  527.                 int sx,sy;
  528.                 if (dxl <= 1)
  529.                     sx = sx1;
  530.                 else
  531.                     sx = sx1+(x-dx1)*(sxl-1)/(dxl-1);
  532.                 if (dyl <= 1)
  533.                     sy = sy1;
  534.                 else
  535.                     sy = sy1+(y-dy1)*(syl-1)/(dyl-1);
  536.                 int c;
  537.                 c = EIMpoint_back(sx,sy);
  538.                 EIMpset(x,y,c,blkop);
  539.             }
  540.         }
  541. #endif
  542.     }
  543. }
  544.  
  545.  
  546.  
  547.  
  548. static void commandZoom_sub(int method)
  549. {
  550.     for(;;)
  551.     {
  552.         if (area_input(method) != 0)
  553.             break;
  554.         int ax1,ay1,ax2,ay2;
  555.         area_getboundxy(&ax1,&ay1,&ax2,&ay2);
  556.         int step = 0;  // 0:転送先始点指定中  1:転送先終点指定中
  557.         int dx1=0,dy1=0;
  558.         void drawcsr(int msx,int msy)
  559.         {
  560.             MOFF;
  561.             int tx=DMimage_getx(msx), ty=DMimage_gety(msy);
  562.             if (step==1)
  563.             {
  564.                 int xr=ax2-ax1,yr=ay2-ay1;
  565.                 if (xr>0 && yr>0)
  566.                 {
  567.                     if (xr>yr)
  568.                     {
  569.                         int r = (yr<<16) / xr;
  570.                         int xmax = EIMgetxsize()-1;
  571.                         int y1 = (r * dx1)>>16, y2 = (r * (xmax-dx1))>>16;
  572.                         EIMline(0,dy1-y1,xmax,dy1+y2,white,DrawXOR);
  573.                         EIMline(0,dy1+y1,xmax,dy1-y2,white,DrawXOR);
  574.                     }
  575.                     else
  576.                     {
  577.                         int r = (xr<<16) / yr;
  578.                         int ymax = EIMgetysize()-1;
  579.                         int x1 = (r * dy1)>>16, x2 = (r * (ymax-dy1))>>16;
  580.                         EIMline(dx1-x1,0,dx1+x2,ymax,white,DrawXOR);
  581.                         EIMline(dx1+x1,0,dx1-x2,ymax,white,DrawXOR);
  582.                     }
  583.                 }
  584.                 EIMboxline(dx1,dy1,tx,ty,white,DrawXOR);
  585.             }
  586.             MON;
  587.         }
  588.         area_drawbound();
  589.         for (;;)
  590.         {
  591.             int prex,prey;
  592.             if (step == 0)
  593.                 DMdispcsr(ms.x,ms.y);
  594.             drawcsr((prex=ms.x),(prey=ms.y));
  595.             do {
  596.                 ms_get(&ms);
  597.             } while (ms.dx==0 && ms.dy==0 && ms.btn1==OFF && ms.btn2==OFF &&
  598.                      key_chk() == 0);
  599.             if (step == 0)
  600.                 DMerasecsr();
  601.             drawcsr(prex,prey);        // 消去
  602.             scrollForCsr(1,1);
  603.             if (ms.btn1 == OFFON)
  604.             {
  605.                 if (step == 0)
  606.                 {
  607.                     step=1;
  608.                     dx1=DMimage_getx(ms.x), dy1=DMimage_gety(ms.y);
  609.                 }
  610.                 else
  611.                 {
  612.                     int dx2,dy2;
  613.                     dx2=DMimage_getx(ms.x),dy2=DMimage_gety(ms.y);
  614.                     area_drawbound();
  615.                     EIMbackup();
  616.                     zoomcopy(ax1,ay1,ax2,ay2, dx1,dy1,dx2,dy2,
  617.                              (blkop==DrawMATTE?YES:NO),YES);
  618.                     area_drawbound();
  619.                     step = 0;
  620.                 }
  621.             }
  622.             if (ms.btn2 == OFFON)
  623.             {
  624.                 if (step == 0)
  625.                     break;
  626.                 else
  627.                     step = 0;
  628.             }
  629.         }
  630.         area_drawbound();
  631.     }
  632. }
  633.  
  634. void commandZoom()
  635. {
  636.     commandZoom_sub(AREA_BOX);
  637. }
  638.  
  639. void commandZoomPoly()
  640. {
  641.     commandZoom_sub(AREA_POLYGON);
  642. }
  643.  
  644.  
  645. static int coldiff(int col1, int col2)
  646. // col1,col2 : 3万色カラーコード
  647. // 返値 : col1 と col2 の違い
  648. {
  649.     int r;
  650.     r = _abs((col1 & 31) - (col2 & 31));
  651.     r += _abs(((col1 >> 5) & 31) - ((col2 >> 5) & 31));
  652.     r += _abs(((col1 >> 10) & 31) - ((col2 >> 10) & 31));
  653.     return r;
  654. }
  655.  
  656.  
  657. static int colmazeru(int c1, int c2, int pow)
  658. // pow : 混色率 0..256
  659. {
  660.     short int g,r,b;
  661.     short int p1,p2;
  662.     if (pow == 0)
  663.         return c1;
  664.     else if (pow == 256)
  665.         return c2;
  666.     p1 = 256-pow;
  667.     p2 = pow;
  668.     g = (((c1>>10)&31)*p1+((c2 >> 10) & 31)*p2+128)/256;
  669.     r = (((c1 >>  5) & 31)*p1+((c2 >>  5) & 31)*p2+128)/256;
  670.     b = ((c1 & 31)*p1+(c2 & 31)*p2+128)/256;
  671.     return (int)((g<<10)+(r<<5)+b);
  672. }
  673.  
  674.  
  675.  
  676. #define    HTURN    1
  677. #define    VTURN    2
  678.  
  679. static void commandCopyPoly_sub(int method,int turn)
  680. {
  681.     int lat2xlen,lat2ylen;
  682.     DMimage_getlatticesize(&lat2xlen,&lat2ylen);
  683.     for(;;)
  684.     {
  685.         if (area_input(method) != 0)
  686.             break;
  687.         int ax1,ay1,ax2,ay2;
  688.         area_getboundxy(&ax1,&ay1,&ax2,&ay2);
  689.         void drawcsr(int msx,int msy)
  690.         {
  691.             MOFF;
  692.             int tx=DMimage_getx(msx), ty=DMimage_gety(msy);
  693.             if (areaadj && method == AREA_BOX)
  694.                 tx = tx - tx % lat2xlen, ty = ty - ty % lat2ylen;
  695.             EIMrboxline(tx,ty,ax2-ax1+1,ay2-ay1+1,white,DrawXOR);
  696.             MON;
  697.         }
  698.         area_drawbound();  // 転送元ボックス表示
  699.         int zr = DMimage_getzoomrate();
  700.         scrollForCsr((ax2-ax1+1)*zr,(ay2-ay1+1)*zr);
  701.         for (;;)
  702.         {
  703.             int prex,prey;
  704.             if (method == AREA_BOX && areaadj)
  705.                 DMdispcsr(ms.x,ms.y);
  706.             drawcsr((prex=ms.x),(prey=ms.y));
  707.             do {
  708.                 ms_get(&ms);
  709.             } while (ms.dx==0 && ms.dy==0 && ms.btn1==OFF && ms.btn2==OFF &&
  710.                      key_chk() == 0);
  711.             if (method == AREA_BOX && areaadj)
  712.                 DMerasecsr();
  713.             drawcsr(prex,prey);        // 消去
  714.             scrollForCsr((ax2-ax1+1)*zr,(ay2-ay1+1)*zr);
  715.             // scrollForCsr(1,1);
  716.             if (ms.btn1 == OFFON)
  717.             {
  718.                 area_drawbound();  // 転送元ボックス消去
  719.                 EIMbackup();
  720.                 int dx,dy;
  721.                 dx = DMimage_getx(ms.x),  dy = DMimage_gety(ms.y);
  722.                 if (areaadj && method == AREA_BOX)
  723.                     dx = dx - dx % lat2xlen,  dy = dy - dy % lat2ylen;
  724.                 int x,y;
  725.                 char *lbuf = LINnew();
  726.                 if(lbuf == NULL)
  727.                     goto _endturn;
  728.                 for (y=ay1; y<=ay2; y++)
  729.                 {
  730.                     x = ax1 + area_chkxylen(ax1,ax2,y,YES);
  731.                     while (x<=ax2)
  732.                     {
  733.                         int l;
  734.                         if ((l = area_chkxylen(x,ax2,y,NO)) == 0)
  735.                             break;
  736.                         if (turn == 0)
  737.                         {
  738.                             matte_hline_map(dx+(x-ax1),dx+(x+l-1-ax1),
  739.                                             dy+(y-ay1),EIMadrs_back(x,y),
  740.                                             blkop);
  741.                         }
  742.                         else if (turn & VTURN)
  743.                         {
  744.                             matte_hline_map(dx+(x-ax1),dx+(x+l-1-ax1),
  745.                                             dy+(ay2-y),EIMadrs_back(x,y),
  746.                                             blkop);
  747.                         }
  748.                         else if (turn & HTURN)
  749.                         {
  750.                             memcpy(lbuf,EIMadrs_back(x,y),l*2);
  751.                             int i,t;
  752.                             for (i=0; i<l/2; i++)
  753.                             {
  754.                                 #define    SA(a,i)    *((short*)(a)+(i))
  755.                                 t = SA(lbuf,i);
  756.                                 SA(lbuf,i)=SA(lbuf,l-1-i);
  757.                                 SA(lbuf,l-1-i)=t;
  758.                                 #undef    SA
  759.                             }
  760.                             matte_hline_map(dx+(ax2-(x+l-1)),dx+(ax2-x),
  761.                                             dy+(y-ay1), lbuf,blkop);
  762.                         }
  763.                         x += l + area_chkxylen(x+l,ax2,y,YES);
  764.                     }
  765.                 }
  766.                 LINdelete(lbuf);
  767.                 _endturn:
  768.                 area_drawbound();  // 転送元ボックス表示
  769.             }
  770.             if (ms.btn2 == OFFON)
  771.                 break;
  772.         }
  773.         area_drawbound();  // 転送元ボックス消去
  774.     }
  775. }
  776.  
  777. void commandCopyPoly()
  778. {
  779.     commandCopyPoly_sub(AREA_POLYGON, 0);
  780. }
  781.  
  782.  
  783. void commandCopy()
  784. {
  785.     commandCopyPoly_sub(AREA_BOX,0);
  786. }
  787.  
  788.  
  789. void commandCopyPolyHturn()
  790. {
  791.     commandCopyPoly_sub(AREA_POLYGON, HTURN);
  792. }
  793.  
  794. void commandCopyPolyVturn()
  795. {
  796.     commandCopyPoly_sub(AREA_POLYGON, VTURN);
  797. }
  798.  
  799. void commandCopyHturn()
  800. {
  801.     commandCopyPoly_sub(AREA_BOX,HTURN);
  802. }
  803.  
  804. void commandCopyVturn()
  805. {
  806.     commandCopyPoly_sub(AREA_BOX,VTURN);
  807. }
  808.  
  809.  
  810. /* end of copy.c */
  811.  
  812.